package com.atguigu.jxc.service.impl;

import com.atguigu.jxc.dao.SaleGoodsDao;

import com.atguigu.jxc.dao.SaleListGoodsDao;
import com.atguigu.jxc.dao.UserDao;
import com.atguigu.jxc.domain.SaleDataByMonthVo;
import com.atguigu.jxc.domain.SaleListVo;
import com.atguigu.jxc.entity.*;
import com.atguigu.jxc.service.*;
import com.atguigu.jxc.util.DateUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author: lshuaib
 * @create: 2021-03-08 11:54
 * @description:
 */
@Service
public class SaleGoodsServiceImpl implements SaleGoodsService {
    @Resource
    SaleGoodsDao saleGoodsDao;
    @Resource
    SaleListGoodsService saleListGoodsService;
    @Resource
    GoodsService goodsService;
    @Resource
    LogService logService;
    @Resource
    UserService userService;
    @Resource
    CustomerService customerService;
    @Resource
    UserDao userDao;
    @Resource
    SaleListGoodsDao saleListGoodsDao;

    @Override
    @Transactional
    public void save(String saleNumber, SaleList saleList, String saleListGoodsStr, HttpSession session) {
        Gson gson = new Gson();
        saleList.setSaleNumber(saleNumber);
        String userName = (String) userService.loadUserInfo(session).get("userName");
        User user = new User();
        user.setUserName(userName);
        User userInfo = userService.getUserInfo(user);

        saleList.setUserId(userInfo.getUserId());
        //保存销售订单
        saleGoodsDao.save(saleList);
        logService.save(new Log(Log.INSERT_ACTION, "保存销售订单" + saleList.getSaleListId()));
        List<SaleListGoods> saleListGoodsList = gson.fromJson(saleListGoodsStr, new TypeToken<List<SaleListGoods>>() {
        }.getType());
        //保存销售订单项,并且减少库存
        saleListGoodsList.forEach(saleListGoods -> {
            saleListGoods.setSaleListId(saleList.getSaleListId());
            saleListGoodsService.add(saleListGoods);
            logService.save(new Log(Log.INSERT_ACTION, "添加库存项: " + saleListGoods.getSaleListGoodsId()));
            goodsService.reduceStock(saleListGoods.getGoodsCode(), saleListGoods.getGoodsNum());
            logService.save(new Log(Log.UPDATE_ACTION, "减少的库存编号:" + saleListGoods.getGoodsCode()));
        });
    }

    @Override
    public Map<String, Object> list(String saleNumber, Integer customerId, Integer state, String sTime, String eTime) {
        List<SaleList> saleLists = saleGoodsDao.selectSaleGoods(saleNumber, customerId, state, sTime, eTime);
        List<SaleListVo> saleListVos = saleLists.stream().map(saleList -> {
            SaleListVo sl = new SaleListVo();
            BeanUtils.copyProperties(saleList, sl);
            Customer customer = customerService.getCustomerById(sl.getCustomerId());
            sl.setCustomerName(customer.getCustomerName());
            User user = userDao.getUserById(sl.getUserId());
            sl.setTrueName(user.getTrueName());


            return sl;
        }).collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>();
        map.put("rows", saleListVos);
        return map;
    }

    @Override
    public List<Map<String, Object>> getSaleDataByMonth(String sTime, String eTime) {
        List<Map<String, Object>> mapList = new LinkedList<>();

        List<String> months = null;
        try {
            months = DateUtil.getTimeSlotByMonth(sTime, eTime);
        } catch (Exception e) {
            e.printStackTrace();
        }
        assert months != null;
        months.forEach(month -> {
            List<SaleDataByMonthVo> vos = saleGoodsDao.getSaleDataByMonth(month);
            double saleTotalPrice = vos.stream().filter(vo -> {
                return vo != null && vo.getPrice() != 0;
            }).mapToDouble(SaleDataByMonthVo::getPrice).sum();
            double purPrice = vos.stream().filter(vo -> {
                return vo != null && vo.getGoodsCode() != null;
            }).map(SaleDataByMonthVo::getGoodsCode).mapToDouble(goodsCode -> goodsService.getPriceByCode(goodsCode)).sum();
            Map<String, Object> map = new HashMap<>();
            map.put("date", month);
            map.put("saleTotal", saleTotalPrice);
            map.put("purchasingTotal", purPrice);
            map.put("profit", saleTotalPrice - purPrice);
            mapList.add(map);
        });

        return mapList;
    }

    @Override
    public void delete(Integer saleListId) {
        saleGoodsDao.delete(saleListId);
        saleListGoodsDao.deleteBySaleListId(saleListId);
    }
}
